package com.pdool.game.core.msg;

import cn.hutool.core.util.ReflectUtil;
import com.google.protobuf.Parser;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * 加载msgId对应的处理器
 */
@Component
public class MsgRegPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

        Class<?> targetClass = AopUtils.getTargetClass(bean);
        MsgHandler annotation = targetClass.getAnnotation(MsgHandler.class);
        if (annotation != null && bean instanceof IHandler) {
            try {
                IHandler handlerBean = (IHandler) bean;
                int msgId = annotation.value();
//                System.out.println(targetClass.getGenericInterfaces());
//                System.out.println(targetClass.getSuperclass());
                Type[] genericSuperclass = targetClass.getGenericInterfaces();
                ParameterizedType type = (ParameterizedType) genericSuperclass[0];
                Type[] actualTypeArguments = type.getActualTypeArguments();
                Class in = (Class) actualTypeArguments[0];
                Class out = (Class) actualTypeArguments[1];

                Method inParserMethod = ReflectUtil.getMethod(in, "parser");
                Method outBuilder = ReflectUtil.getMethod(out, "outBuilder");


                Parser inParser = (Parser) inParserMethod.invoke(null);
//                Parser outParser = (Parser) outParserMethod.invoke(null);
                MsgHandlerItem msgHandlerItem = new MsgHandlerItem(msgId, inParser, outBuilder, handlerBean);
                MsgMgr.getHandlerMap().put(msgId, msgHandlerItem);
            } catch (Exception e) {
                //  TODO 报错内容
            }

        }

        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }
}
